home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 20 / Cream of the Crop 20 (Terry Blount) (1996).iso / os2 / souper15.zip / KILL.C < prev    next >
C/C++ Source or Header  |  1996-05-18  |  5KB  |  220 lines

  1. /* $Id: kill.c 1.3 1996/05/18 21:11:10 cthuang Exp $
  2.  *
  3.  * Kill file processing
  4.  */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include "regexp.h"
  10. #include "souper.h"
  11.  
  12. /* kill regular expression */
  13. typedef struct aKillExp {
  14.     struct aKillExp *next;    /* next in list */
  15.     regexp *re;            /* compiled regular expression */
  16. } KillExp;
  17.  
  18. /* kill file entry for a newsgroup */
  19. typedef struct aGroupKill {
  20.     struct aGroupKill *next;    /* next in list */
  21.     char *name;            /* newsgroup name */
  22.     KillExp *expList;        /* list of kill expressions */
  23. } GroupKill;
  24.  
  25. static GroupKill *globalKill;        /* global kill */
  26. static GroupKill *groupKillList;    /* list of group specific kills */
  27. static GroupKill *curGroupKill;        /* current group kill */
  28.  
  29. /* Function called for an error when compiling regular expression. */
  30.  
  31. void
  32. regerror (const char *msg)
  33. { }
  34.  
  35. /* Copy string.  Return pointer to '\0' at end of destination string. */
  36.  
  37. char *
  38. stpcpy (char *dest, const char *src)
  39. {
  40.     while ((*dest++ = *src++) != '\0')
  41.     ;
  42.     return dest - 1;
  43. }
  44.  
  45. #ifndef HAVE_STRLWR
  46. char *
  47. strlwr (char *str)
  48. {
  49.     char *p = str;
  50.     while (*p != '\0') {
  51.     if (isascii(*p))
  52.         *p = tolower(*p);
  53.     ++p;
  54.     }
  55.     return str;
  56. }
  57. #endif
  58.  
  59. /* Read kill file expression.
  60.  */
  61. static KillExp *
  62. readKillExp (FILE *inf, const char *searchIn)
  63. {
  64.     char searchFor[BUFSIZ], exp[BUFSIZ], *p;
  65.     KillExp *result;
  66.  
  67.     if (!fgets(searchFor, sizeof(searchFor), inf) || searchFor[0] == '\n')
  68.     return NULL;
  69.     if ((p = strchr(searchFor, '\n')) != NULL)
  70.     *p = '\0';
  71.  
  72.     if (stricmp(searchIn, "header") == 0) {
  73.     strcpy(exp, searchFor);
  74.     } else {
  75.     p = exp;
  76.     *p++ = '^';
  77.     p = stpcpy(p, searchIn);
  78.     p = stpcpy(p, ":.*");
  79.     p = stpcpy(p, searchFor);
  80.     *p = '\0';
  81.     }
  82.  
  83.     result = (KillExp *)xmalloc(sizeof(KillExp));
  84.     result->next = NULL;
  85.     strlwr(exp);
  86.     result->re = regcomp(exp);
  87.     return result;
  88. }
  89.  
  90. /* Read kill file and compile regular expressions.
  91.  * Return TRUE if successful.
  92.  */
  93. int
  94. readKillFile (void)
  95. {
  96.     char buf[BUFSIZ], name[FILENAME_MAX], searchIn[FILENAME_MAX];
  97.     FILE *inf;
  98.     GroupKill *pGroup, *pLastGroup;
  99.     KillExp *pExp, *pLastExp;
  100.     char ok;
  101.  
  102.     globalKill = groupKillList = NULL;
  103.  
  104.     if ((inf = fopen(killFile, "r")) == NULL) {
  105.     return 0;
  106.     }
  107.  
  108.     pLastGroup = NULL;
  109.     ok = 1;
  110.  
  111.     /* Read newsgroup name. */
  112.     while (ok && fscanf(inf, "%s", name) == 1) {
  113.     /* Read opening brace. */
  114.     fscanf(inf, "%s", buf);
  115.     if (buf[0] != '{' || buf[1] != '\0') {
  116.         ok = 0;
  117.         break;
  118.     }
  119.  
  120.     if (stricmp(name, "all") == 0) {
  121.         /* Allocate global kill entry. */
  122.         if (globalKill == NULL)
  123.         globalKill = (GroupKill *)xmalloc(sizeof(GroupKill));
  124.         pGroup = globalKill;
  125.     } else {
  126.         /* Allocate group kill entry. */
  127.         pGroup = (GroupKill *)xmalloc(sizeof(GroupKill));
  128.         pGroup->name = xstrdup(name);
  129.         pGroup->next = NULL;
  130.  
  131.         if (pLastGroup == NULL)
  132.         groupKillList = pGroup;
  133.         else
  134.         pLastGroup->next = pGroup;
  135.         pLastGroup = pGroup;
  136.     }
  137.     pGroup->expList = NULL;
  138.  
  139.     /* Read kill expressions until closing brace. */
  140.     pLastExp = NULL;
  141.     while (fscanf(inf, "%s ", searchIn) == 1) {
  142.         if (searchIn[0] == '}' && searchIn[1] == '\0')
  143.         break;
  144.         if ((pExp = readKillExp(inf, searchIn)) == NULL) {
  145.         ok = 0;
  146.         break;
  147.         }
  148.  
  149.         if (pLastExp == NULL)
  150.         pGroup->expList = pExp;
  151.         else
  152.         pLastExp->next = pExp;
  153.         pLastExp = pExp;
  154.     }
  155.     }
  156.     fclose(inf);
  157.  
  158.     if (!ok)
  159.     fprintf(stderr, "%s: error in kill file %s\n", progname, killFile);
  160.     return ok;
  161. }
  162.  
  163. /* Set current group kill.
  164.  * Return TRUE if global kills exist or specific group kill exists.
  165.  */
  166. int
  167. killGroup (const char *name)
  168. {
  169.     GroupKill *p;
  170.  
  171.     for (p = groupKillList; p != NULL; p = p->next) {
  172.     if (stricmp(p->name, name) == 0) {
  173.         curGroupKill = p;
  174.         return 1;
  175.     }
  176.     }
  177.     curGroupKill = NULL;
  178.     return globalKill != NULL || maxLines > 0;
  179. }
  180.  
  181. /* Check if line matches any expression in the group kill entry.
  182.  * Return TRUE if article should be killed.
  183.  */
  184. static int
  185. matchLine (GroupKill *pGroup, const char *buf)
  186. {
  187.     KillExp *pExp;
  188.  
  189.     if (pGroup == NULL)
  190.     return 0;
  191.  
  192.     for (pExp = pGroup->expList; pExp != NULL; pExp = pExp->next) {
  193.     if (regexec(pExp->re, buf))
  194.         return 1;
  195.     }
  196.     return 0;
  197. }
  198.  
  199. /* Check if line matches kill criteria.
  200.  * Return TRUE if article should be killed.
  201.  */
  202. int
  203. killLine (const char *line)
  204. {
  205.     char buf[BUFSIZ];
  206.  
  207.     strncpy(buf, line, sizeof(buf)-1);
  208.     buf[sizeof(buf)-1] = '\0';
  209.     strlwr(buf);
  210.  
  211.     if (maxLines > 0 && strncmp(buf, "lines: ", 7) == 0) {
  212.     if (atoi(buf+7) > maxLines)
  213.         return 1;
  214.     }
  215.  
  216.     if (matchLine(globalKill, buf))
  217.     return 1;
  218.     return matchLine(curGroupKill, buf);
  219. }
  220.